#pragma once
#include <typescommon.h>

// protocol Parse Common Step Enum
enum ptcPsStpEnum
{
    ptcPsStpFixHd = 0, // fixed head
    ptcPsStpVers,      // version
    ptcPsStpVerHd,     // version head
    ptcPsStpData,      // data
};
// protocol Parse version Enum
enum ptcPsVersEnum
{
    ptcPsVers0 = 0, // version 0
    ptcPsVers1,     // version 1
    ptcPsVers2,     // version 2
    ptcPsVers3,     // version 3
};
// protocol Parse crypte Enum
enum ptcPsCryptEnum
{
    ptcPsCryptNone = 0,
    ptcPsCryptAes,
    ptcPsCryptRsa,
    ptcPsCryptSm4,
    ptcPsCryptSm2,
    ptcPsCryptDes3,
    ptcPsCryptAesPre,
    ptcPsCryptSm4Pre,
    //
};
// PTC:protocol
#define PTC_PACK_BEGIN_PST 0    // begin position
#define PTC_PACK_VER_PST 3      // version position
#define PTC_PACK_VER_HEAD_PST 4 // version head position
// VERSION 1
#define PTC_PACK_V1_SIZE_PST 4                                                // version 1 size position
#define PTC_PACK_V1_ADDR_PST 6                                                // version 1 addr position
#define PTC_PACK_V1_ENCYPT_PST 10                                             // version 1 encrypte position
#define PTC_PACK_V1_ADDR_SIZE (PTC_PACK_V1_ENCYPT_PST - PTC_PACK_V1_ADDR_PST) // version 1 addr SIZE
#define PTC_PACK_V1_CRC_PST 11                                                // version 1 crc position
#define PTC_PACK_V1_DATA_PST 12                                               // version 1 data position
// VERSION 2
// #define PTC_PACK_V2_SIZE_PST 4                                                // version 2 size position
// #define PTC_PACK_V2_ENCYPT_PST 8                                             // version 2 encrypte position
// #define PTC_PACK_V2_COMPRESS_PST 9                                             // version 2 compress position
// #define PTC_PACK_V2_CRC_PST 10                                                // version 2 crc position
// #define PTC_PACK_V2_DATA_PST 12                                               // version 2 data position


typedef uint16_t ptcPackType;

// protocol Parse operate struct
struct ptcOptPsStruct
{
    ptcPackType pksize;   // pkptr's size
    ptcPackType rcvCount; // receive counter
    ptcPackType needSize; // receive need size
    uint8_t parseState;   // parse state
    uint8_t myVersion;    // my version
    uint8_t pkptr[1];     // pack buffer
};
#define ptcPsOptComSize (offsetof(struct ptcOptPsStruct, pkptr))
int ptcOptInit(void *ptcPtr, ptcPackType setPackSize, uint8_t setver);
int ptcOptPsData(void *ptcPtr, uint8_t indata);
// void ptcPsOptCbk(void *ptcPtr);

ptcPackType ptcOptGetHeadSize(void *ptcPtr);
ptcPackType ptcOptGetTotalSize(void *ptcPtr);
ptcPackType ptcOptGetRemainSize(void *ptcPtr);

uint8_t ptcOptGetVersion(void *ptcPtr);
int ptcOptSetVersion(void *ptcPtr, uint8_t setCrypte);

#define ptcOptGetPackPtr(ptcPtr) (((struct ptcOptPsStruct *)ptcPtr)->pkptr)

ptcPackType ptcOptGetDataSize(void *ptcPtr);
int ptcOptSetDataSize(void *ptcPtr, ptcPackType setsize);

const uint8_t *ptcOptGet485Addr(void *ptcPtr);
int ptcOptSet485Addr(void *ptcPtr, const uint8_t *setAddr);

int ptcOptCheckAddr(void *ptcPtr, const uint8_t *myaddr);

uint8_t ptcOptGetCrypte(void *ptcPtr);
int ptcOptSetCrypte(void *ptcPtr, uint8_t setCrypte);

uint8_t *ptcOptGetUsrData(void *ptcPtr);
int ptcOptSetUsrData(void *ptcPtr, const uint8_t *usrData, ptcPackType dsize);

ptcPackType ptcOptFinPack(void *ptcPtr);
